package main

import (
	"fmt"
	"github.com/samber/do"
)

type UserRepository struct{}

func NewUserRepository() *UserRepository {
	return &UserRepository{}
}

func (r *UserRepository) GetUser(id int) string {
	return fmt.Sprintf("User %d", id)
}

type UserService struct {
	repo *UserRepository
}

func NewUserService(i *do.Injector) (*UserService, error) {
	repo := do.MustInvoke[*UserRepository](i)
	return &UserService{repo: repo}, nil
}

func (s *UserService) GetUserName(id int) string {
	return s.repo.GetUser(id)
}

func main() {
	// 1. 创建一个新的注入器
	injector := do.New()

	// 2. 注册服务
	// 注册 UserRepository
	do.Provide(injector, func(i *do.Injector) (*UserRepository, error) {
		return NewUserRepository(), nil
	})
	// 注册 UserService
	do.Provide(injector, NewUserService)

	// 3. 获取并使用服务
	userService := do.MustInvoke[*UserService](injector)

	userName := userService.GetUserName(42)
	fmt.Println(userName) // 输出: User 42

	// 4. 关闭注入器，释放所有服务
	injector.Shutdown()
}
